// Copyright (C) 2006 Taylor L. Riché <riche@cs.utexas.edu>
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

#ifndef PACKET_HH
#define PACKET_HH

#include <assert.h>
#include "fivetuple.hh"
#include <lagniappe/RData.h>
#include <lagniappe/Operator.h>


// The following code is borrowed from the libnet project, and
// falls under the following license:

// START LIBNET CODE
 
/*  Copyright (c) 1998 - 2004 Mike D. Schiffman
    <mike@infonexus.com>
    * All rights reserved. 
    * 
    * Redistribution and use in source and binary forms, with or without 
    * modification, are permitted provided that the following conditions 
    * are met: 
    * 1. Redistributions of source code must retain the above copyright 
    *    notice, this list of conditions and the following disclaimer. 
    * 2. Redistributions in binary form must reproduce the above copyright 
    *    notice, this list of conditions and the following disclaimer in the 
    *    documentation and/or other materials provided with the distribution. 
    * 
    * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 
    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
    * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 
    * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
    * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
    * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
    * SUCH DAMAGE. 
    *  
    */

/* used internally for checksum stuff */
#define CKSUM_CARRY(x) \
  (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))

// END LIBNET CODE

namespace pktTypes {

typedef char * payload_t;

class Packet
{
protected:
  payload_t payload;
  uint16_t length;
  // The following code is borrowed from the libnet project, and
  // falls under the following license:
  
  // START LIBNET CODE
  
  /*  Copyright (c) 1998 - 2004 Mike D. Schiffman
      <mike@infonexus.com>
      * All rights reserved. 
      * 
      * Redistribution and use in source and binary forms, with or without 
      * modification, are permitted provided that the following conditions 
      * are met: 
      * 1. Redistributions of source code must retain the above copyright 
      *    notice, this list of conditions and the following disclaimer. 
      * 2. Redistributions in binary form must reproduce the above copyright 
      *    notice, this list of conditions and the following disclaimer in the 
      *    documentation and/or other materials provided with the distribution. 
      * 
      * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 
      * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
      * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
      * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 
      * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
      * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
      * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
      * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
      * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
      * SUCH DAMAGE. 
      *  
      */
  
  int in_cksum(u_int16_t *addr, int len) {
    int sum;      
    sum = 0;      
    while (len > 1) {
      sum += *addr++;
      len -= 2;
    }     
    if (len == 1) {
      sum += *(u_int16_t *)addr;
    }      
    return (sum); 
  }
  
  // END LIBNET CODE
  
public:
  Packet() : payload(NULL), length(0) {}
  Packet(payload_t p, uint16_t l) : payload(p), length(l) {}
  Packet(lagniappe::RData * p, uint16_t l) : payload((payload_t)p), length(l) {}
  virtual ~Packet() {}
  inline void setPayload(char * const p) {payload = p; return;}
  inline payload_t getPayload() const {return payload;}
  virtual int chksum() {return 0;}
  inline lagniappe::RData * getRData() const {return static_cast<lagniappe::RData *>(payload);}
  uint16_t getLength() const {return length;}
  void setLength(uint16_t l) {length = l;}
  lagniappe::FlowID getFiveTupleID();
  static lagniappe::FlowID getFiveTupleID(tt::FiveTuple & ft);
  lagniappe::FlowID getSixFiveTupleID();
  lagniappe::FlowID getUDPFiveTupleID();
  lagniappe::FlowID getUDPSixFiveTupleID();
};

}

#endif // PACKET_HH
